﻿using System;
using System.Windows.Forms;
using Microsoft.Office.Interop.Outlook;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using Outlook.WorkItems.Extension.Addin.Actions;
using Outlook.WorkItems.Extension.Manager.TeamProjectManager;
using Outlook.WorkItems.Extension.Controls;

namespace Outlook.WorkItems.Extension.Addin.Forms
{
    /// <summary>
    /// Link Manager Form between MAPIFolder and Team Project
    /// </summary>
    internal partial class FolderLinkTeamProjectForm : Form
    {
        #region Fields

        /// <summary>
        /// MAPIFolder
        /// </summary>
        private readonly MAPIFolder _folder;
        /// <summary>
        /// Team Project Name
        /// </summary>
        private string _projectName;
        /// <summary>
        /// TFS Name
        /// </summary>
        private string _serverName;
        /// <summary>
        /// Work Item Store
        /// </summary>
        private WorkItemStore _wiStore;
        /// <summary>
        /// Action
        /// </summary>
        private CreateWiAction _wiAction;
        /// <summary>
        /// Action
        /// </summary>
        private UploadAttachmentsAction _upAction;

        private bool _isInit;
        private string _serverUri;

        #endregion

        /// <summary>
        /// Default Constructor.
        /// </summary>
        public FolderLinkTeamProjectForm()
        {
            InitializeComponent();
        }

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="folder">MAPIFloder to manage link</param>
        public FolderLinkTeamProjectForm(MAPIFolder folder)
            : this()
        {
            _folder = folder;
            Text += string.Format(" - {0}", _folder.Name);

            var linkExist = TeamProjectLinksManager.ContainsTeamProjectLink(_folder.EntryID);

            try
            {
                if (linkExist)
                {
                    var link = TeamProjectLinksManager.GetTeamProjectLink(_folder.EntryID);
                    _projectName = link.TeamProjectName;
                    _serverName = link.TeamServerName;
                    _wiAction = link.CreateWiAction;
                    _serverUri = link.TeamServerUri;
                    _wiStore = TeamProjectLinksManager.GetWorkItemStore(link.TeamServerUri);
                    _upAction = link.UploadAttachmentsAction;

                    InitPanelWorkItemCreation();
                    InitPanelUploadAttachments();

                    chkCreateWorkItem.Checked = link.CreateWiAction != null;
                    chkAddAttachMailToAttachWI.Checked = link.CreateWiAction != null && link.CreateWiAction.AddMessageAttachments;
                    chkAddMailToWIAttach.Checked = link.CreateWiAction != null && link.CreateWiAction.AddMessageToAttachmentWi;
                    checkBox1.Checked = link.CreateWiAction != null && link.CreateWiAction.TrackConversationInWorkItem;
                    textBox1.Text = string.Format("{0} - {1}", _serverName, _projectName);
                    btnRemoveLink.Enabled = true;
                }
                else
                {
                    textBox1.Text = null;
                    chkUploadAttachments.Enabled = false;
                    btnSelectDestination.Enabled = false;
                    txtFileExtensions.Enabled = false;
                }
            }
            catch (System.Exception ex)
            {
                using (var frm = new ErrorForm(ex))
                {
                    frm.ShowDialog();
                }
            }

            chkCreateWorkItem.Enabled = _wiStore != null;
            btnRemoveLink.Enabled = linkExist;
            btnOk.Enabled = linkExist;
            cbWorkItemTypes.Enabled = linkExist && _wiAction != null;
            btnDefineMapping.Enabled = linkExist && _wiAction != null;
            chkAddAttachMailToAttachWI.Enabled = linkExist && _wiAction != null;
            chkAddMailToWIAttach.Enabled = linkExist && _wiAction != null;
            checkBox1.Enabled = linkExist && _wiAction != null;
            cbFormat.Enabled = linkExist && _wiAction != null && _wiAction.AddMessageToAttachmentWi;
        }


        private void InitPanelUploadAttachments()
        {

            _isInit = true;
            if (_upAction != null)
            {
                chkUploadAttachments.Checked = true;
                txtPath.Text = _upAction.DestinationPath;
                txtFileExtensions.Text = _upAction.FileExtensions;
            }
            else if (_upAction == null || string.IsNullOrEmpty(_upAction.DestinationPath))
            {
                chkUploadAttachments.Checked = false;
                txtPath.Text = "";
            }
            _isInit = false;
        }

        private void InitPanelWorkItemCreation()
        {
            try
            {
                WorkItemTypeItem witiToSelect = null;
                string wiName = null;
                if (_wiAction != null && _wiAction.Mapping != null)
                {
                    wiName = _wiAction.Mapping.WorkItemType;
                }
                cbWorkItemTypes.Items.Clear();
                foreach (WorkItemType item in _wiStore.Projects[_projectName].WorkItemTypes)
                {
                    var witi = new WorkItemTypeItem(item);
                    cbWorkItemTypes.Items.Add(witi);
                    if (item.Name == wiName)
                        witiToSelect = witi;
                }
                if (witiToSelect != null)
                {
                    cbWorkItemTypes.SelectedItem = witiToSelect;
                }
                else if (cbWorkItemTypes.Items.Count > 0)
                {
                    cbWorkItemTypes.SelectedIndex = 0;
                }
            }
            catch (System.Exception ex)
            {
                using (var frm = new ErrorForm(ex))
                {
                    frm.ShowDialog();
                }
            }

            cbFormat.Items.Clear();
            var index = cbFormat.Items.Add(new FormatMail(OlSaveAsType.olTXT, "Text only (*.txt)"));
            cbFormat.SelectedIndex = (_wiAction != null && _wiAction.FormatMail == OlSaveAsType.olTXT.ToString()) ? index : cbFormat.SelectedIndex;
            index = cbFormat.Items.Add(new FormatMail(OlSaveAsType.olMSG, "Outlook Message Format (*.msg)"));
            cbFormat.SelectedIndex = (_wiAction != null && _wiAction.FormatMail == OlSaveAsType.olMSG.ToString()) ? index : cbFormat.SelectedIndex;
            index = cbFormat.Items.Add(new FormatMail(OlSaveAsType.olMSGUnicode, "Outlook Message Format - Unicode (*.msg)"));
            cbFormat.SelectedIndex = (_wiAction != null && _wiAction.FormatMail == OlSaveAsType.olMSGUnicode.ToString()) ? index : cbFormat.SelectedIndex;
            index = cbFormat.Items.Add(new FormatMail(OlSaveAsType.olHTML, "HTML (*.htm;*.html)"));
            cbFormat.SelectedIndex = (_wiAction != null && _wiAction.FormatMail == OlSaveAsType.olHTML.ToString()) ? index : cbFormat.SelectedIndex;
            index = cbFormat.Items.Add(new FormatMail(OlSaveAsType.olMHTML, "MHT Files (*.mht)"));
            cbFormat.SelectedIndex = (_wiAction != null && _wiAction.FormatMail == OlSaveAsType.olMHTML.ToString()) ? index : cbFormat.SelectedIndex;
        }

        /// <summary>
        /// Manage selection of a Team Project
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSelectTP_Click(object sender, EventArgs e)
        {
            try
            {
                using (var frm = new SelectTeamProjectForm())
                {
                    if (frm.ShowDialog() == DialogResult.OK)
                    {
                        Cursor = Cursors.WaitCursor;
                        _projectName = frm.ProjectName;
                        
                        _serverUri = frm.ServerUri;
                        var server = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri(_serverUri));
                        _serverName = server.Name;
                        _wiStore = server.GetService<WorkItemStore>();
                        textBox1.Text = string.Format("{0} - {1}", _serverName, _projectName);
                        btnOk.Enabled = true;
                        chkCreateWorkItem.Enabled = true;
                        chkUploadAttachments.Enabled = true;
                        btnSelectDestination.Enabled = true;
                        txtFileExtensions.Enabled = true;

                        InitPanelWorkItemCreation();
                    }
                }
            }
            catch (System.Exception ex)
            {
                using (var frm = new ErrorForm(ex))
                {
                    frm.ShowDialog(this);
                }
            }
            finally
            {
                Cursor = Cursors.Default;
            }
        }

        /// <summary>
        /// Save settings
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnOk_Click(object sender, EventArgs e)
        {
            try
            {
                if (_wiAction != null && (_wiAction.Mapping == null || (_wiAction.Mapping.MappingFields == null || _wiAction.Mapping.MappingFields.Count == 0)))
                {
                    MessageBox.Show("You must define mapping");
                    return;
                }
                if (chkUploadAttachments.Checked)
                {
                    _upAction.FileExtensions = txtFileExtensions.Text;
                }
                TeamProjectLinksManager.AddTeamProjectLink(_folder.EntryID, _folder.StoreID, _serverName, _serverUri, _projectName, _wiAction, _upAction);
                DialogResult = DialogResult.OK;
                Close();
            }
            catch (System.Exception ex)
            {
                using (var frm = new ErrorForm(ex))
                {
                    frm.ShowDialog();
                }
            }
        }

        /// <summary>
        /// Enable or disable settings button
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void chkCreateWorkItem_CheckedChanged(object sender, EventArgs e)
        {

            if (chkCreateWorkItem.Checked == false)
            {
                _wiAction = null;
            }
            else
            {
                if (_wiAction == null)
                {
                    _wiAction = new CreateWiAction();
                }
            }
            cbWorkItemTypes.Enabled = chkCreateWorkItem.Checked;
            btnDefineMapping.Enabled = chkCreateWorkItem.Checked;
            chkAddAttachMailToAttachWI.Enabled = chkCreateWorkItem.Checked;
            chkAddMailToWIAttach.Enabled = chkCreateWorkItem.Checked;
            cbFormat.Enabled = chkAddMailToWIAttach.Checked;
            checkBox1.Enabled = chkCreateWorkItem.Checked;
        }

        /// <summary>
        /// Remove existing link between current MAPIFolder and Team Project and save it
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnRemoveLink_Click(object sender, EventArgs e)
        {
            try
            {
                TeamProjectLinksManager.RemoveProjectLink(_folder.EntryID);
                Close();
            }
            catch (System.Exception ex)
            {
                using (var frm = new ErrorForm(ex))
                {
                    frm.ShowDialog();
                }
            }

        }

        private void FolderLinkTeamProjectForm_Load(object sender, EventArgs e)
        {

        }

        private void btnDefineMapping_Click(object sender, EventArgs e)
        {
            try
            {
                var witi = cbWorkItemTypes.SelectedItem as WorkItemTypeItem;
                if (witi != null)
                {
                    using (var frm = new WorkItemMappingForm(_folder.Application, witi.WorkItemType, new OutlookMailItem((MailItem)_folder.Application.CreateItem(OlItemType.olMailItem)), _wiAction.Mapping))
                    {
                        if (frm.ShowDialog(this) == DialogResult.OK)
                        {
                            _wiAction.Mapping = frm.WorkItemMapping;
                            _wiAction.Mapping.WorkItemType = ((WorkItemTypeItem)cbWorkItemTypes.SelectedItem).WorkItemType.Name;
                        }
                    }
                }
            }
            catch (System.Exception ex)
            {
                using (var frm = new ErrorForm(ex))
                {
                    frm.ShowDialog();
                }
            }
        }

        private void cbFormat_SelectedIndexChanged(object sender, EventArgs e)
        {
            var format = cbFormat.SelectedItem as FormatMail;
            if (format != null && _wiAction != null)
            {
                _wiAction.FormatMail = format.Format.ToString();
            }
        }

        private void chkAddMailToWIAttach_CheckedChanged(object sender, EventArgs e)
        {
            cbFormat.Enabled = chkAddMailToWIAttach.Checked;
            if (_wiAction != null)
            {
                _wiAction.AddMessageToAttachmentWi = chkAddMailToWIAttach.Checked;
            }
        }

        private void chkAddAttachMailToAttachWI_CheckedChanged(object sender, EventArgs e)
        {
            if (_wiAction != null)
            {
                _wiAction.AddMessageAttachments = chkAddAttachMailToAttachWI.Enabled;
            }
        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            if (_wiAction != null)
            {
                _wiAction.TrackConversationInWorkItem = checkBox1.Checked;
            }
        }

        private void cbWorkItemTypes_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (!(cbWorkItemTypes.SelectedItem is WorkItemTypeItem) || _wiAction == null) 
                return;

            if (_wiAction.Mapping == null)
            {
                _wiAction.Mapping = new WorkItemMapping();
            }
            _wiAction.Mapping.WorkItemType = ((WorkItemTypeItem)cbWorkItemTypes.SelectedItem).WorkItemType.Name;
        }

        private void btnSelectDestination_Click(object sender, EventArgs e)
        {
            using (var frm = new SelectLibrairyForm(_projectName))
            {
                if (frm.ShowDialog() != DialogResult.OK) 
                    return;

                _upAction = new UploadAttachmentsAction() { DestinationPath = frm.Path };
                txtPath.Text = frm.Path;
            }
        }

        private void chkUploadAttachments_CheckedChanged(object sender, EventArgs e)
        {
            if (_isInit) 
                return;

            if (chkUploadAttachments.Checked)
            {
                btnSelectDestination.Enabled = true;
                txtFileExtensions.Enabled = true;
                _upAction = new UploadAttachmentsAction();
            }
            else
            {
                btnSelectDestination.Enabled = false;
                txtFileExtensions.Enabled = false;
                _upAction = null;
            }
        }
    }

    /// <summary>
    /// This type is used to display Work Item Types in combobox
    /// </summary>
    internal class WorkItemTypeItem
    {
        public WorkItemType WorkItemType { get; private set; }

        public WorkItemTypeItem(WorkItemType workItemType)
        {
            WorkItemType = workItemType;
        }

        public override string ToString()
        {
            return WorkItemType.Name;
        }
    }
}
